package com.domain;

import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.gui.QueryListener;
import com.persistence.ConfigurationReader;
import com.persistence.DBManipulator;
import com.persistence.KBManipulator;

import com.domain.cumanager.CUManager;
import com.domain.exceptions.CoordinatorFailedToInitException;
import com.domain.exceptions.FailedToAnalyseException;
import com.domain.exceptions.FailedToDispatchPlans;
import com.gui.FormListener;


public class Coordinator extends Thread{
	private ConfigurationReader m_configReader;
	private DBManipulator m_dbManipulator;
	private KBManipulator m_kbManipulator;
	private CUManager m_cuManager;
	private LinkedBlockingQueue<KBTAQuery> m_queryList;
	private boolean m_shouldRun = true;
	private static Logger s_logger;
	private QueryAnalyser m_queryAnalyser;

	public Coordinator(LinkedBlockingQueue<KBTAQuery> queryQueue) throws CoordinatorFailedToInitException{
		super("Coordinator");
		m_queryList = queryQueue;
		m_shouldRun = true;		
		this.init();		
	}

	private void init(){
		m_configReader = new ConfigurationReader();
		m_configReader.loadConfigFile();

		m_dbManipulator = new DBManipulator(m_configReader);
		m_dbManipulator.setUpConnection();

		m_kbManipulator = new KBManipulator(m_configReader);
		m_kbManipulator.loadKBInfo();

		m_cuManager = new CUManager();
		//		m_cuManager.start();		
		
		m_queryAnalyser = new QueryAnalyser();
	}

	public void run(){
		s_logger.info("Starts ...");
		while(m_shouldRun){
			try {
				s_logger.info("Trying to get next query");
				KBTAQuery query = m_queryList.take();
				s_logger.info("Received query. id :" + query.getId());
				TasksArray plansArray = m_queryAnalyser.analyse(query);
				m_cuManager.dispatchPlans(plansArray);
				addPendingPlans(plansArray);
			} 
			catch (InterruptedException e) {				
				s_logger.warn("Failed to take query from Queue");
			} 
			catch (FailedToAnalyseException e) {
				s_logger.warn("Failed to analyse query");
				//TODO handle this case. may be need to insert query again into the queue
				//e.printStackTrace();
			}
			catch (FailedToDispatchPlans e) {
				//TODO handle this case. regard different strategies
				//e.printStackTrace();
				s_logger.warn("Failed to dispatch plans");
			}			
		}
		s_logger.info("Was stopped. Exits ...");
	}


	private void addPendingPlans(TasksArray plansArray) {
		// TODO Auto-generated method stub
		
	}

	public static void main(String[] args) {
		try{
			s_logger = Logger.getLogger(Coordinator.class);
			PropertyConfigurator.configure("D:/workspace/DKBTA/files/conf/log4j.properties");
			LinkedBlockingQueue<KBTAQuery> queryQueue = new LinkedBlockingQueue<KBTAQuery>();		
			//QueryListener queryListener = new QueryListener(queryQueue);
                        QueryListener queryListener = new FormListener(queryQueue);
			queryListener.start();
			Coordinator coordinator = new Coordinator(queryQueue);		
			coordinator.start();
		}
		catch(Exception e){
			System.err.println("The system failed to start. see logs");
		}
	}

}
